package db

import (
	"errors"
	"hr/api/dto"

	"github.com/spf13/cast"
	"gorm.io/gorm"
)

// FormalApproval 转正申请
type FormalApproval struct {
	AppModel
	UserID          string `gorm:"size:64" json:"user_id"`
	EntryTime       string `gorm:"size:64" json:"entry_time"`
	ProbationPeriod string `gorm:"size:64" json:"probation_period"` //试用期
	FormalTime      string `gorm:"size:64" json:"formal_time"`      //转正日期
	WorkExperience  string `json:"work_experience"`                 //工作感受
	CreateBy        string `gorm:"size:128" json:"createBy"`        // 创建人
	UpdateBy        string `gorm:"size:128" json:"updateBy"`        // 更新人
	Remark          string `gorm:"size:255" json:"remark"`          //备注
	OrderStatus     string `gorm:"size:64;" json:"order_status"`    // 申请状态 1保存、2提交、3撤销
	ApprovalStatus  string `gorm:"size:64;" json:"approval_status"` // 是否同意 1是2否
	RefuseReason    string `json:"refuseReason"`
}

func (u *FormalApproval) TableName() string {
	return "approval_formal"
}

type FormalApprovalName struct {
	FormalApproval
	UserName string `json:"user_name"`
}

type FormalApprovalPageModel struct {
	Total    int64                `json:"total"`
	Result   []FormalApprovalName `json:"result"`
	PageNo   int                  `json:"pageNo"`
	PageSize int                  `json:"pageSize"`
}

func GetFormalApprovalPaging(pagination dto.Pagination, name string, userId uint, from string) (FormalApprovalPageModel, error) {
	user := GetUserById(userId)
	role := GetRoleById(user.RoleID)
	result := FormalApprovalPageModel{
		Total:    0,
		Result:   make([]FormalApprovalName, 0),
		PageNo:   pagination.PageNo,
		PageSize: pagination.PageSize,
	}
	offset := (pagination.PageNo - 1) * pagination.PageSize
	dbs := GetInstance().Select("approval_formal.*,concat(IFNULL(user.name,''),'(',user.nick_name,')') as user_name").Joins("left join user on approval_formal.create_by = user.id")
	if from == "1" && role.Code == "small_captain" {
		dbs = dbs.Where("user.dept_id=?", user.DeptID).Where("approval_formal.approval_status='3'").Order("approval_formal.created_at desc")
	} else {
		if role.Code == "supper" {
			dbs = dbs.Where("approval_formal.approval_status!='3'").Order("approval_formal.created_at desc")
		} else {
			dbs = dbs.Where("approval_formal.create_by = ?", userId).Order("approval_formal.created_at desc")
		}
	}

	if err := dbs.Offset(offset).Limit(pagination.PageSize).Find(&result.Result).Error; err != nil {
		return result, err
	}
	if err := dbs.Offset(-1).Limit(-1).Count(&result.Total).Error; err != nil {
		return result, err
	}
	return result, nil
}

func GetFormalApproval(p map[string]interface{}, extra ...interface{}) (FormalApproval, error, string) {
	f := FormalApproval{}
	queryDb := GetInstance().Where(p).First(&f)
	if len(extra) > 0 {
		queryDb = queryDb.Where(extra)
	}
	err := queryDb.Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return f, errors.New("查无记录"), "0"
		}
		return f, errors.New(err.Error()), "1"
	}
	return f, nil, "2"
}

func CreateFormalApproval(p FormalApproval, userId string) (FormalApproval, error) {
	approval := p.ApprovalStatus
	if p.OrderStatus == "2" {
		user := GetUserById(cast.ToUint(userId))
		isCaptain := HasSmallCaptain(user.DeptID)
		if isCaptain {
			approval = "3"
		}
	}
	d := FormalApproval{
		UserID:          p.UserID,
		EntryTime:       p.EntryTime,
		ProbationPeriod: p.ProbationPeriod,
		FormalTime:      p.FormalTime,
		WorkExperience:  p.WorkExperience,
		CreateBy:        userId,
		Remark:          p.Remark,
		OrderStatus:     p.OrderStatus,
		ApprovalStatus:  approval,
		RefuseReason:    p.RefuseReason,
	}
	if err := GetInstance().Create(&d).Error; err != nil {
		return d, errors.New("创建失败")
	}
	return d, nil
}

func UpdateFormalApproval(id uint, p FormalApproval, user string) (FormalApproval, error) {
	f := FormalApproval{
		AppModel: AppModel{
			ID: id,
		},
	}
	err := GetInstance().Model(&f).Updates(FormalApproval{
		UserID:          p.UserID,
		EntryTime:       p.EntryTime,
		ProbationPeriod: p.ProbationPeriod,
		FormalTime:      p.FormalTime,
		WorkExperience:  p.WorkExperience,
		UpdateBy:        user,
		Remark:          p.Remark,
		OrderStatus:     p.OrderStatus,
		ApprovalStatus:  p.ApprovalStatus,
		RefuseReason:    p.RefuseReason,
	}).Updates(map[string]interface{}{
		"id": id,
	}).Scan(&f).Error
	if err != nil {
		return f, err
	}
	return f, nil
}

func DeleteFormalApproval(id uint) (FormalApproval, error) {
	f := FormalApproval{}
	err := GetInstance().Unscoped().Where("id = ?", id).Delete(&f).Error
	if err != nil {
		return f, err
	}
	return f, nil
}

func UpdateFormalApprovalOrderStatus(id uint, status string, userId uint) (FormalApproval, error) {
	approval := ""
	if status == "2" {
		user := GetUserById(userId)
		isCaptain := HasSmallCaptain(user.DeptID)
		if isCaptain {
			approval = "3"
		}
	}
	f := FormalApproval{
		AppModel: AppModel{
			ID: id,
		},
	}
	err := GetInstance().Model(&f).Updates(map[string]interface{}{
		"order_status":    status,
		"approval_status": approval,
	}).Scan(&f).Error
	if err != nil {
		return f, err
	}
	return f, nil
}

func UpdateFormalApprovalApprovalStatus(p dto.ApprovalRequest, id uint) (FormalApproval, error) {
	f := FormalApproval{
		AppModel: AppModel{
			ID: id,
		},
	}
	err := GetInstance().Model(&f).Updates(map[string]interface{}{
		"refuse_reason":   p.RefuseReason,
		"approval_status": p.ApprovalStatus,
	}).Scan(&f).Error
	if err != nil {
		return f, err
	}
	return f, nil
}
